﻿#include "IPAddressEdit.h"

#include <QRegExp>
#include <QRegExpValidator>
#include <QApplication>
#include <QClipboard>
#include <QLayout>
#include <QEvent>
#include <QKeyEvent>

namespace GeneralUI {

	IPAddressEdit::IPAddressEdit(QWidget *parent) 
		: QWidget(parent)
	{
		m_backgroundColor = "#FFFFFF";
		m_borderColor = "#A6B5B8";
		m_borderRadius = 10;

		m_pLabelDot1 = new QLabel(this);
		m_pLabelDot1->setAlignment(Qt::AlignCenter);
		m_pLabelDot1->setText(".");

		m_pLabelDot2 = new QLabel(this);
		m_pLabelDot2->setAlignment(Qt::AlignCenter);
		m_pLabelDot2->setText(".");

		m_pLabelDot3 = new QLabel(this);
		m_pLabelDot3->setAlignment(Qt::AlignCenter);
		m_pLabelDot3->setText(".");

		m_pLineEditIP1 = new QLineEdit;
		m_pLineEditIP1->setObjectName("lineEditIP1");
		m_pLineEditIP1->setAlignment(Qt::AlignCenter);
		m_pLineEditIP1->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
		connect(m_pLineEditIP1, SIGNAL(textChanged(QString)), this, SLOT(textChanged(QString)));

		m_pLineEditIP2 = new QLineEdit;
		m_pLineEditIP2->setObjectName("lineEditIP2");
		m_pLineEditIP2->setAlignment(Qt::AlignCenter);
		m_pLineEditIP2->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
		connect(m_pLineEditIP2, SIGNAL(textChanged(QString)), this, SLOT(textChanged(QString)));

		m_pLineEditIP3 = new QLineEdit;
		m_pLineEditIP3->setObjectName("lineEditIP3");
		m_pLineEditIP3->setAlignment(Qt::AlignCenter);
		m_pLineEditIP3->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
		connect(m_pLineEditIP3, SIGNAL(textChanged(QString)), this, SLOT(textChanged(QString)));

		m_pLineEditIP4 = new QLineEdit;
		m_pLineEditIP4->setObjectName("lineEditIP4");
		m_pLineEditIP4->setAlignment(Qt::AlignCenter);
		m_pLineEditIP4->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
		connect(m_pLineEditIP4, SIGNAL(textChanged(QString)), this, SLOT(textChanged(QString)));

		QRegExp regExp("(2[0-4]\\d|25[0-5]|[01]?\\d\\d?)");
		QRegExpValidator *validator = new QRegExpValidator(regExp, this);
		m_pLineEditIP1->setValidator(validator);
		m_pLineEditIP2->setValidator(validator);
		m_pLineEditIP3->setValidator(validator);
		m_pLineEditIP4->setValidator(validator);

		m_pLineEditIP1->setContextMenuPolicy(Qt::NoContextMenu);
		m_pLineEditIP2->setContextMenuPolicy(Qt::NoContextMenu);
		m_pLineEditIP3->setContextMenuPolicy(Qt::NoContextMenu);
		m_pLineEditIP4->setContextMenuPolicy(Qt::NoContextMenu);

		m_pLineEditIP1->installEventFilter(this);
		m_pLineEditIP2->installEventFilter(this);
		m_pLineEditIP3->installEventFilter(this);
		m_pLineEditIP4->installEventFilter(this);

		QFrame *frame = new QFrame(this);
		frame->setObjectName("frameIP");

		updateStyleSheet();

		QVBoxLayout *verticalLayout = new QVBoxLayout(this);
		verticalLayout->setMargin(0);
		verticalLayout->setSpacing(0);
		verticalLayout->addWidget(frame);

		QHBoxLayout *layout = new QHBoxLayout(frame);
		layout->setMargin(0);
		layout->setSpacing(0);
		layout->addWidget(m_pLineEditIP1);
		layout->addWidget(m_pLabelDot1);
		layout->addWidget(m_pLineEditIP2);
		layout->addWidget(m_pLabelDot2);
		layout->addWidget(m_pLineEditIP3);
		layout->addWidget(m_pLabelDot3);
		layout->addWidget(m_pLineEditIP4);
	}

	IPAddressEdit::~IPAddressEdit()
	{

	}

	bool IPAddressEdit::setIPAddress(const QString &strIP)
	{
		//先检测IP地址是否合法
		QRegExp regExp("((2[0-4]\\d|25[0-5]|[01]?\\d\\d?)\\.){3}(2[0-4]\\d|25[0-5]|[01]?\\d\\d?)");
		if (!regExp.exactMatch(strIP))
		{
			return false;
		}

		if (strIP != m_strIPAddress)
		{
			m_strIPAddress = strIP;
			QStringList list = m_strIPAddress.split(".");
			m_pLineEditIP1->setText(list.at(0));
			m_pLineEditIP2->setText(list.at(1));
			m_pLineEditIP3->setText(list.at(2));
			m_pLineEditIP4->setText(list.at(3));
			m_pLineEditIP4->setFocus();
			m_pLineEditIP4->setCursorPosition(m_pLineEditIP4->text().size());
		}
		return true;
	}

	QString IPAddressEdit::getIPAddress() const
	{
		if (m_pLineEditIP1->text().isEmpty() || m_pLineEditIP2->text().isEmpty() ||
			m_pLineEditIP3->text().isEmpty() || m_pLineEditIP4->text().isEmpty())
		{
			return "";
		}

		return m_strIPAddress;
	}

	void IPAddressEdit::setBackgroundColor(const QString &bgColor)
	{
		if (m_backgroundColor != bgColor)
		{
			m_backgroundColor = bgColor;
			this->updateStyleSheet();
		}
	}

	void IPAddressEdit::setBorderColor(const QString &borderColor)
	{
		if (m_borderColor != borderColor)
		{
			m_borderColor = borderColor;
			this->updateStyleSheet();
		}
	}

	void IPAddressEdit::setBorderRadius(int borderRadius)
	{
		if (m_borderRadius != borderRadius)
		{
			m_borderRadius = borderRadius;
			this->updateStyleSheet();
		}
	}

	void IPAddressEdit::clear()
	{
		m_pLineEditIP1->clear();
		m_pLineEditIP2->clear();
		m_pLineEditIP3->clear();
		m_pLineEditIP4->clear();
		m_pLineEditIP1->setFocus();
	}

	QSize IPAddressEdit::sizeHint() const
	{
		return QSize(250, 30);
	}

	QSize IPAddressEdit::minimumSizeHint() const
	{
		return QSize(50, 30);
	}

	bool IPAddressEdit::eventFilter(QObject *watched, QEvent *event)
	{
		QLineEdit* lineEditIP = qobject_cast<QLineEdit*>(watched);
		if (lineEditIP)
		{
			if (event->type() == QEvent::KeyPress)
			{
				QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
				if (keyEvent->key() == Qt::Key_Period)                 //如果当前按下了小数点则移动焦点到下一个输入框
				{
					if (!lineEditIP->text().isEmpty())                  //文本框不为空时后移
					{
						this->focusNextChild();
						QLineEdit* lineEditNext = qobject_cast<QLineEdit*>(focusWidget());
						lineEditNext->selectAll();
					}
				}
				else if (keyEvent->key() == Qt::Key_Backspace && lineEditIP->cursorPosition() == 0)    //如果当前按下了小数点则移动焦点到下一个输入框
				{

					if (lineEditIP != m_pLineEditIP1 && focusNextPrevChild(false))
					{
						QLineEdit* lineEditPrev = qobject_cast<QLineEdit*>(focusWidget());
						lineEditPrev->setCursorPosition(lineEditPrev->text().size());
						lineEditPrev->backspace();
					}
				}
				else if (keyEvent->key() == Qt::Key_Left && lineEditIP->cursorPosition() == 0)
				{
					if (lineEditIP != m_pLineEditIP1 && focusNextPrevChild(false))
					{
						QLineEdit* lineEditPrev = qobject_cast<QLineEdit*>(focusWidget());
						lineEditPrev->setCursorPosition(lineEditPrev->text().size());

					}
				}
				else if (keyEvent->key() == Qt::Key_Right && lineEditIP->cursorPosition() == lineEditIP->text().size())
				{
					if (lineEditIP != m_pLineEditIP4 && focusNextPrevChild(true))
					{
						QLineEdit* lineEditNext = qobject_cast<QLineEdit*>(focusWidget());
						lineEditNext->setCursorPosition(0);
					}
					return false;
				}
				else if (keyEvent->matches(QKeySequence::Paste))
				{
					QClipboard* clipBoard = QApplication::clipboard();
					QString strIP = clipBoard->text();
					setIPAddress(strIP);
					return  false;
				}
			}
			else if (event->type() == QEvent::InputMethod)
			{
				QInputMethodEvent* inputMethodEvent = static_cast<QInputMethodEvent*>(event);
				QString strText = inputMethodEvent->commitString();
				QString strText2 = inputMethodEvent->preeditString();
				if (strText.contains("。") && !lineEditIP->text().isEmpty())
				{
					this->focusNextChild();
					QLineEdit* lineEditNext = qobject_cast<QLineEdit*>(focusWidget());
					lineEditNext->selectAll();
				}
			}
		}
		return QWidget::eventFilter(watched, event);
	}

	void IPAddressEdit::textChanged(const QString &text)
	{
		int len = text.length();
		int value = text.toInt();
		if (len == 3)
		{
			if (value >= 100 && value <= 255)
			{
				this->focusNextChild();
			}
		}

		m_strIPAddress = QString("%1.%2.%3.%4").arg(m_pLineEditIP1->text().toInt()).arg(m_pLineEditIP2->text().toInt()).
			arg(m_pLineEditIP3->text().toInt()).arg(m_pLineEditIP4->text().toInt());
	}

	void IPAddressEdit::updateStyleSheet()
	{
		QStringList qss;
		qss.append(QString("QFrame#frameIP{border:1px solid %1;border-radius:%2px;}").arg(m_borderColor).arg(m_borderRadius));
		qss.append(QString("QLabel{min-width:15px;background-color:%1;}").arg(m_backgroundColor));
		qss.append(QString("QLineEdit{background-color:%1;border:none;}").arg(m_backgroundColor));
		qss.append(QString("QLineEdit#lineEditIP1{border-top-left-radius:%1px;border-bottom-left-radius:%1px;}").arg(m_borderRadius));
		qss.append(QString("QLineEdit#lineEditIP4{border-top-right-radius:%1px;border-bottom-right-radius:%1px;}").arg(m_borderRadius));
		setStyleSheet(qss.join(""));
	}

}
